package com.shopping.es.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.shopping.common.entity.Good;
import com.shopping.common.result.PageResult;
import com.shopping.common.result.Result;
import com.shopping.common.utils.StringUtils;
import com.shopping.es.service.EsService;
import lombok.extern.log4j.Log4j2;
import org.apache.http.HttpHost;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
@Log4j2
public class EsServiceImpl implements EsService {

    /**
     * 初始化ES的客户端
     */
    RestHighLevelClient client = new RestHighLevelClient(
            RestClient.builder(
                    new HttpHost("106.15.183.39", 9200, "http")));

    /**
     * 索引名称
     */
    private static final String INDEX_NAME = "good";

    /**
     * 添加商品
     * @param list
     */
    @Override
    public void addGood(List<Good> list) {
        // 1： 创建索引请求对象
        IndexRequest indexRequest = new IndexRequest(INDEX_NAME);
        for (Good good : list) {
            try {
            // 添加
            indexRequest.id(good.getId()+"");
            // 3: 将请求数据序列化成 JSON 字符串
            String jsonString = JSONObject.toJSONString(good);
            // 4: 设置 source
            indexRequest.source(jsonString, XContentType.JSON);
            // 5: 发送请求
            client.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("功能名称：ES添加修改文章实现异常，请求参数：【{}】，异常信息是：【{}】", JSONObject.toJSONString(good), e);
        }
        }
    }

    /**
     * 高亮查寻
     * @param name
     * @return
     */
    @Override
    public Result<PageResult<Good>> findGoodByName(String name) {
        // 总记录数
        long total = 0;
        // 结果集
        List<Good> list = new ArrayList<>();
        try {
            // 1: 创建搜索请求对象
            SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
            // 2: 构建 搜索请求数据 构建对象
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            // 3: 构建查询条件拼接对象
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            // 4: 拼接查询条件
            if (StringUtils.isNotEmpty(name)) {
                boolQueryBuilder.must(QueryBuilders.matchQuery("name", name));
            }
            // 放入查询条件
            searchSourceBuilder.query(boolQueryBuilder);

            // 设置查询条件
            searchRequest.source(searchSourceBuilder);
            // 高亮
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            // 设置高亮字段
            highlightBuilder.field("name");
            // 设置前置标签
            highlightBuilder.preTags("<span style=\"color:red;\">");
            // 设置后置标签
            highlightBuilder.postTags("</span>");
            // 添加到 sourceBuilder
            searchSourceBuilder.highlighter(highlightBuilder);
            // 发送 请求
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            // 处理相应结果
            SearchHits searchHits = searchResponse.getHits();
            // 设置总记录数
            total = searchHits.getTotalHits().value;
            // 获取搜索结果
            SearchHit[] hits = searchHits.getHits();
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                // 反序列化
                Good good = JSONObject.parseObject(sourceAsString, Good.class);
                // 替换 高亮内容
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (highlightFields != null) {
                    HighlightField highlightField = highlightFields.get("name");
                    if (highlightField != null) {
                        Text[] fragments = highlightField.fragments();
                        String str = "";
                        for (Text fragment : fragments) {
                            str += fragment;
                        }
                        good.setName(str);
                    }
                }
                // 设置id
                good.setId(Integer.parseInt(hit.getId()));
                // 添加到结果集
                list.add(good);
            }
            // 返回结果
            return PageResult.toResult(total, list);
        } catch(Exception ex) {
            log.error("功能名称：ES搜索文章异常，请求参数：【{}】，异常信息：【{}】", name, ex);
        }
        return null;
    }

}
